import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jverify/jverify.dart';
import 'package:sainbainu/common/apis/login_api.dart';
import 'package:sainbainu/common/http/exception.dart';
import 'package:sainbainu/common/models/request/apple_auth_request.dart';
import 'package:sainbainu/common/models/request/jverify_login_request.dart';
import 'package:sainbainu/common/repositories/login_repository.dart';
import 'package:sainbainu/common/routes/routes.dart';
import 'package:sainbainu/common/services/apple.dart';
import 'package:sainbainu/common/services/user.dart';
import 'package:sainbainu/common/services/wechat.dart';
import 'package:sainbainu/common/utils/custom_exception.dart';
import 'package:sainbainu/common/utils/loading.dart';
import 'package:sainbainu/common/utils/system_toast.dart';
import 'package:sainbainu/common/values/colors.dart';
import 'package:sainbainu/common/values/settings.dart';
import 'package:sign_in_with_apple/sign_in_with_apple.dart';

import 'jpush.dart';

/// 是否是苹果设备
final bool isApple = Platform.isIOS || Platform.isMacOS;

class JverifyService extends GetxService {
  static JverifyService get to => Get.find();

  late Jverify _jverify;

  /// 是否已经预取号
  bool _isPreLogin = false;
  bool get isPreLogin => _isPreLogin;

  /// 是否初始化成功
  bool _isInitSuccess = false;
  bool get isInitSuccess => _isInitSuccess;

  /// 是否勾选协议
  bool _isAgreeChecked = false;

  /// 登录仓库
  late LoginRepository _loginRepository;

  JverifyService();

  @override
  void onInit() {
    super.onInit();
    _init();
    _loginRepository = LoginRepository(LoginApi());
  }

  /// 初始化 SDK
  _init() {
    _jverify = Jverify();
    // 初始化 SDK 之前添加监听
    _jverify.addSDKSetupCallBackListener((JVSDKSetupEvent event) {
      _checkInitSuccess();
      _print("sdk 初始化结果 :${event.toMap()}");
    });
    _jverify.setup(
      appKey: AppSettings.jPushAppKey,
      channel: 'developer-default',
    );
    // 打开调试模式
    _jverify.setDebugMode(AppSettings.isDebug);
    // 授权页面事件监听
    _jverify.addAuthPageEventListener((JVAuthPageEvent event) {
      _print("auth page event :${event.toMap()}");
      if (event.code == 6) {
        _isAgreeChecked = true;
      } else if (event.code == 7 || event.code == 1) {
        _isAgreeChecked = false;
      }
    });
  }

  /// 初始化是否成功
  Future<void> _checkInitSuccess() async {
    var res = await _jverify.isInitSuccess();
    bool success = res['result'];
    _isInitSuccess = success;
    _print(success ? '认证SDK初始化成功✅' : '认证SDK初始化失败❌');
  }

  /// 手机网络环境校验
  Future<bool> _checkVerifyEnable() async {
    var res = await _jverify.checkVerifyEnable();
    bool success = res['result'];

    _print(success ? '当前网络环境支持认证✅' : '当前网络环境不支持认证❌');
    return success;
  }

  /// 预取号（加快登录界面弹出）
  Future preLogin() async {
    if (_isPreLogin) return;

    if (!_isInitSuccess) return;

    bool checkVerifySuccess = await _checkVerifyEnable();
    if (!checkVerifySuccess) return;

    var res = await _jverify.preLogin();
    if (res['code'] == 7000) {
      _isPreLogin = true;
    }
  }

  /// 打印
  _print(String message) {
    print('📱📱📱📱📱📱📱📱 $message');
  }

  /// 授权页面
  Future authPage() async {
    if (!_isInitSuccess) {
      throw CustomException('认证 SDK 初始化失败');
    }
    // 检查手机网络环境
    bool checkVerifySuccess = await _checkVerifyEnable();
    if (!checkVerifySuccess) {
      throw CustomException('当前网络不支持一键登录');
    }

    bool isiOS = Platform.isIOS;
    double sw = Get.width;
    double statusBarHeight = Get.statusBarHeight;
    int privacyOffsetY = isiOS ? 40 : 20;
    JVUIConfig uiConfig = JVUIConfig();

    /// 导航
    uiConfig.navHidden = false;
    uiConfig.navReturnImgPath = "launch_return_btn";
    uiConfig.navTransparent = true;
    uiConfig.navText = ' ';

    /// 一键登录顶部Logo
    uiConfig.logoWidth = 300 ~/ 2;
    uiConfig.logoHeight = 67 ~/ 2;
    uiConfig.logoOffsetY = statusBarHeight.toInt() + 30;
    uiConfig.logoVerticalLayoutItem = JVIOSLayoutItem.ItemSuper;
    uiConfig.logoImgPath = "launch_logo_image";

    /// 手机号
    uiConfig.numberFieldWidth = 300;
    uiConfig.numberFieldHeight = 40;
    uiConfig.numFieldOffsetY = 80;
    uiConfig.numberVerticalLayoutItem = JVIOSLayoutItem.ItemLogo;
    uiConfig.numberColor = AppColors.active.value;
    uiConfig.numberTextBold = true;
    uiConfig.numberSize = 36;

    /// 隐藏运营商
    uiConfig.sloganHidden = true;

    /// 登录按钮
    uiConfig.logBtnWidth = 277;
    uiConfig.logBtnHeight = 44;
    uiConfig.logBtnOffsetY = 60;
    uiConfig.logBtnVerticalLayoutItem = JVIOSLayoutItem.ItemNumber;
    uiConfig.logBtnText = "";
    uiConfig.logBtnTextColor = Colors.white.value;
    uiConfig.logBtnTextSize = 16;
    uiConfig.logBtnTextBold = false;
    uiConfig.logBtnBackgroundPath = 'launch_login_btn_normal';
    uiConfig.loginBtnNormalImage = "launch_login_btn_normal";
    uiConfig.loginBtnPressedImage = "launch_login_btn_normal";
    uiConfig.loginBtnUnableImage = "launch_login_btn_normal";

    /// 隐私条款
    uiConfig.privacyHintToast = true; // 仅限 android 设置隐私条款不选中时点击登录按钮默认显示toast
    uiConfig.privacyState = false; //设置默认勾选
    uiConfig.privacyCheckboxSize = 20;
    uiConfig.checkedImgPath = "launch_check_image"; //图片必须存在
    uiConfig.uncheckedImgPath = "launch_un_check_image"; //图片必须存在
    uiConfig.privacyCheckboxInCenter = true;
    uiConfig.privacyCheckboxHidden = false;
    uiConfig.isAlertPrivacyVc = false;
    uiConfig.privacyOffsetY = privacyOffsetY; // 距离底部距离
    uiConfig.privacyVerticalLayoutItem = JVIOSLayoutItem.ItemSuper;
    uiConfig.clauseBaseColor = AppColors.active.value;
    uiConfig.clauseColor = AppColors.active.value;
    uiConfig.privacyText = ["请阅读并同意"];
    uiConfig.privacyTextSize = 12;
    uiConfig.privacyTextBold = true;
    uiConfig.privacyItem = [
      JVPrivacy("用户协议", AppSettings.userAgreeLink, separator: "、"),
      JVPrivacy("隐私政策", AppSettings.privacyAgreeLink, separator: "以及"),
    ];

    /// 隐私协议 web 页 UI 配置
    uiConfig.privacyNavColor = AppColors.nav.value;
    uiConfig.privacyNavReturnBtnImage = 'launch_return_btn';
    uiConfig.privacyNavTitleTextColor = AppColors.active.value;
    uiConfig.privacyNavTitleTextSize = 16;
    uiConfig.privacyStatusBarStyle = JVIOSBarStyle.StatusBarStyleDefault;

    /// 隐私页
    uiConfig.privacyStatusBarColorWithNav = true;
    uiConfig.privacyVirtualButtonTransparent = true;

    /// 授权页
    uiConfig.statusBarColorWithNav = true;
    uiConfig.virtualButtonTransparent = true;
    uiConfig.authStatusBarStyle = JVIOSBarStyle.StatusBarStyleDefault;

    /// 拉起授权页时是否需要动画
    uiConfig.needStartAnim = true;
    uiConfig.needCloseAnim = true;
    uiConfig.enterAnim = "activity_slide_enter_bottom";
    uiConfig.exitAnim = "activity_slide_exit_bottom";

    /// 添加自定义的 控件 到授权界面
    List<JVCustomWidget> widgetList = [];

    /// 使用其他手机号码登录
    const String btnWidgetId = "other_login_btn";
    JVCustomWidget buttonWidget = JVCustomWidget(
      btnWidgetId,
      JVCustomWidgetType.button,
    );
    buttonWidget.title = "其他方式登录";
    buttonWidget.titleFont = 15;
    buttonWidget.titleColor = AppColors.active2.value;
    buttonWidget.width = 200;
    buttonWidget.height = 30;
    buttonWidget.left = (sw - buttonWidget.width) ~/ 2;
    buttonWidget.top = (statusBarHeight + 310).toInt();
    buttonWidget.textAlignment = JVTextAlignmentType.center;
    _jverify.addClikWidgetEventListener(btnWidgetId, (eventId) {
      if (btnWidgetId == eventId) {
        _otherLogin();
      }
    });
    widgetList.add(buttonWidget);

    /// 微信登录
    if (await WechatService.to.isWeChatInstalled) {
      const String wechatWidgetId = "wechat_login_btn";
      JVCustomWidget wechatWidget = JVCustomWidget(
        wechatWidgetId,
        JVCustomWidgetType.button,
      );
      wechatWidget.btnNormalImageName = 'launch_wechat_image';
      wechatWidget.width = 44;
      wechatWidget.height = 44;
      int left;
      if (isApple) {
        left = (sw / 2 - wechatWidget.width - 10).toInt();
      } else {
        left = (sw / 2 - wechatWidget.width / 2).toInt();
      }
      wechatWidget.left = left;
      wechatWidget.top = (Get.height - privacyOffsetY - 100).toInt();
      _jverify.addClikWidgetEventListener(wechatWidgetId, (eventId) {
        if (wechatWidgetId == eventId) {
          _wechatLogin();
        }
      });
      widgetList.add(wechatWidget);
    }

    /// apple登录
    if (isApple) {
      const String appleWidgetId = "apple_login_btn";
      JVCustomWidget appleWidget = JVCustomWidget(
        appleWidgetId,
        JVCustomWidgetType.button,
      );
      appleWidget.btnNormalImageName = 'launch_apple_image';
      appleWidget.width = 44;
      appleWidget.height = 44;
      appleWidget.left = (sw / 2 + 10).toInt();
      appleWidget.top = (Get.height - privacyOffsetY - 100).toInt();
      _jverify.addClikWidgetEventListener(appleWidgetId, (eventId) {
        if (appleWidgetId == eventId) {
          _appleLogin();
        }
      });
      widgetList.add(appleWidget);
    }

    /// 调用接口设置 UI
    _jverify.setCustomAuthorizationView(
      true,
      uiConfig,
      landscapeConfig: uiConfig,
      widgets: widgetList,
    );

    /// 调用一键登录接口
    _jverify.loginAuthSyncApi2(
      autoDismiss: true,
      loginAuthcallback: (JVListenerEvent event) {
        _print('loginAuthSyncApi2 ${event.toMap()}');
        if (event.code == 6000 && event.message != null) {
          _eazyLogin(event.message!);
        } else if (event.code == 6002) {
          // 取消或关闭 暂不做操作
        } else {
          LoadingUtil.showToast('一键登录失败，已为你切换至短信登录');
          _otherLogin();
        }
      },
    );
  }

  /// 一键登录
  Future _eazyLogin(String loginToken) async {
    _print('一键登录 login token: $loginToken');
    try {
      LoadingUtil.showLoading(text: '登录中');
      var registrationId = await JpushService.to.getRegistrationID();
      var res = await _loginRepository.jpushLogin(JverifyLoginRequest(
        loginToken: loginToken,
        registrationId: registrationId,
      ));
      String token = res['token'] as String;
      UserService.to.setIsLogin(true);
      UserService.to.setToken(token);
      UserService.to.getAccountInfo();
      LoadingUtil.showSuccess('登录成功');
    } on CustomHttpException catch (e) {
      LoadingUtil.showError(e.message);
    } catch (e) {
      LoadingUtil.showError('出错啦～');
    }
  }

  /// 使用其他手机号码登录
  _otherLogin() {
    _jverify.dismissLoginAuthView();
    Get.toNamed(AppRoutes.login);
  }

  /// 微信登录
  Future<void> _wechatLogin() async {
    if (!_isAgreeChecked) {
      return SystemToast.showToast('请阅读并同意协议');
    }
    _jverify.dismissLoginAuthView();
    try {
      LoadingUtil.showLoading();
      await WechatService.to.authCode((String? code) async {
        if (code == null) {
          return LoadingUtil.showError('登录失败！');
        }
        try {
          var registrationId = await JpushService.to.getRegistrationID();
          var res = await _loginRepository.wechatLogin(
            code: code,
            registrationId: registrationId,
          );
          String token = res['token'] as String;
          bool bindedMobile = res['is_mobile'] as bool;
          UserService.to.setIsLogin(true);
          UserService.to.setToken(token);
          UserService.to.getAccountInfo();
          if (!bindedMobile) {
            Get.toNamed(AppRoutes.bindMobile);
          }
          LoadingUtil.showSuccess('登录成功');
        } on CustomHttpException catch (e) {
          LoadingUtil.showError(e.message);
        } catch (e) {
          LoadingUtil.showError('出错啦～');
        }
      }, (err) {
        LoadingUtil.showError('登录失败！');
      });
    } on CustomException catch (e) {
      LoadingUtil.showError(e.toString());
    } catch (e) {
      LoadingUtil.showError('登录失败！');
    }
  }

  /// apple 登录
  _appleLogin() async {
    if (!_isAgreeChecked) {
      return SystemToast.showToast('请阅读并同意协议');
    }
    _jverify.dismissLoginAuthView();
    try {
      LoadingUtil.showLoading();
      final rid = await JpushService.to.getRegistrationID();
      final credential = await AppleService.to.appleAuth();
      final res = await _loginRepository.appleLogin(
        appleAuthRequest: AppleAuthRequest(
          userIdentifier: credential.userIdentifier,
          identityToken: credential.identityToken,
          authorizationCode: credential.authorizationCode,
          givenName: credential.givenName,
        ),
        registrationId: rid,
      );
      String token = res['token'] as String;
      bool bindedMobile = res['is_mobile'] as bool;
      UserService.to.setIsLogin(true);
      UserService.to.setToken(token);
      UserService.to.getAccountInfo();
      if (!bindedMobile) {
        Get.toNamed(AppRoutes.bindMobile);
      }
      LoadingUtil.showSuccess('登录成功');
    } on CustomHttpException catch (e) {
      LoadingUtil.showError(e.message);
    } on CustomException catch (e) {
      LoadingUtil.showError(e.toString());
    } on SignInWithAppleAuthorizationException catch (e) {
      if (e.code != AuthorizationErrorCode.canceled) {
        LoadingUtil.showError('apple 授权失败！');
      } else {
        LoadingUtil.dismiss();
      }
    } catch (e) {
      LoadingUtil.showError('出错啦～');
    }
  }
}
